package avicit.bdp.dds.api.service;

import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.dto.StorageResourceConf;
import avicit.bdp.common.service.service.FileCommonService;
import avicit.bdp.common.service.service.FileOperateCommonService;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.common.utils.CheckParaUtils;
import avicit.bdp.core.constant.Constants;
import avicit.bdp.core.file.util.FileUtils;
import avicit.bdp.dds.apc.dto.ResUploadDto;
import avicit.bdp.dds.apc.utils.enums.ResourceStatus;
import avicit.bdp.dds.api.dto.resources.ResOtherInfoDto;
import avicit.bdp.dds.api.enums.ExecuteType;
import avicit.bdp.dds.dao.entity.Resource;
import avicit.bdp.dds.dao.mapper.ResourceMapper;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.properties.PlatformConstant;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author felix
 * project service
 **/
@Service
public class DdsResourceService extends BaseService<ResourceMapper, Resource> {

    private static final Logger logger = LoggerFactory.getLogger(DdsResourceService.class);

    private static final String RESOURCE_ID = "402883c4742d9edb52742da6da1c0005";

    private final ResourceMapper resourceMapper;
    private final ConvertColumnClient convertColumnClient;
    private final FileOperateCommonService fileOperateCommonService;
    private final ExecutorService execService;
    private final FileCommonService fileCommonService;

    @Autowired
    public DdsResourceService(ResourceMapper resourceMapper,
                              ConvertColumnClient convertColumnClient,
                              FileOperateCommonService fileOperateCommonService,
                              ExecutorService execService,
                              FileCommonService fileCommonService) {

        this.resourceMapper = resourceMapper;
        this.convertColumnClient = convertColumnClient;
        this.fileOperateCommonService = fileOperateCommonService;
        this.execService = execService;
        this.fileCommonService = fileCommonService;
    }

    /**
     * 查询文件目录树形展示
     *
     * @param projectId 项目空间ID
     * @return 文件目录
     */
    @Transactional(readOnly = true)
    public List<Resource> findResourceTree(String projectId, Boolean flag) {
        try {
            //顶级节点
            List<Resource> list = Lists.newArrayList();
            //子节点数据
            Map<String, List<Resource>> map = Maps.newHashMap();
            //记录日志
            Resource resource = new Resource();
            resource.setPid("-1");
            List<Resource> topResources = selectList(resource);

            StorageResourceConf storageResourceConf = fileOperateCommonService.getStorageResourceConf(projectId);
            if (storageResourceConf == null) {
                return list;
            }

            Resource resourceDTO = new Resource();
            resourceDTO.setProjectId(projectId);
            resourceDTO.setType(Resource.TYPE_RESOURCE);
            resourceDTO.setEngineResourceId(storageResourceConf.getId());
            if (!flag) {
                resourceDTO.setDirectory(Resource.DIRECTORY_FOLDER);
            }
            List<Resource> childrenResources = selectList(resourceDTO);
            List<Resource> dataList = Stream.of(topResources, childrenResources)
                    .flatMap(Collection::stream)
                    .distinct()
                    .sorted(Comparator.comparing(Resource::getCreationDate).reversed())
                    .collect(Collectors.toList());

            if (CollectionUtils.isNotEmpty(dataList)) {
                for (Resource resources : dataList) {
                    if ("-1".equals(resources.getPid())) {
                        list.add(resources);
                    } else {
                        if (map.containsKey(resources.getPid())) {
                            List<Resource> resourceList = map.get(resources.getPid());
                            resourceList.add(resources);
                        } else {
                            List<Resource> resourcesDTOList = Lists.newArrayList();
                            resourcesDTOList.add(resources);
                            map.put(resources.getPid(), resourcesDTOList);
                        }
                    }
                }
            }
            listConvert(list, map);
            return list;
        } catch (Exception e) {
            throw new BusinessException(e.getMessage(), e);
        }
    }

    /**
     * 递归查询目录
     *
     * @param list list
     */
    private void listConvert(List<Resource> list, Map<String, List<Resource>> map) {
        for (Resource resource : list) {
            List<Resource> resourceList = map.get(resource.getId());
            if (resourceList != null && resourceList.size() > 0) {
                listConvert(resourceList, map);
                resource.setChildren(resourceList);
            } else {
                if (resource.getPid() != null && "-1".equals(resource.getPid())) {
                    resource.setChildren(new ArrayList<>());
                } else {
                    resource.setChildren(null);
                }

            }
        }
    }

    /**
     * 新增目录/文件
     *
     * @param pid       pid
     * @param remark    remark
     * @param file      file
     * @param projectId projectId
     * @param directory directory
     * @return 目录/文件 ID
     */
    @Transactional(rollbackFor = Exception.class)
    public String insertForDirectory(String name, String pid, String remark, MultipartFile file,
                                     String projectId, int directory) {
        try {
            if (directory == Resource.DIRECTORY_FILE && file != null) {
                //文件大小判断，不能超过1G
                if (file.getSize() > Constants.GB_IN_BYTES) {
                    logger.error("file size is too large, more than 1GB.: {}", file.getOriginalFilename());
                    throw new BusinessException("文件大于1G，不能上传");
                }
            }
            fileOperateCommonService.getStorageAndSetThreadLocal(projectId);

            Resource resource = new Resource();
            StorageResourceConf storageResourceConf = fileOperateCommonService.getStorageResourceConf(projectId);

            String baseFilePath = fileOperateCommonService.getDDSStoragePath(storageResourceConf);


            resource.setId(ComUtil.getId());
            resource.setPid(pid);
            resource.setRemark(remark);
            resource.setProjectId(projectId);
            resource.setDirectory(directory);
            resource.setName(name);
            resource.setEngineResourceId(storageResourceConf.getId());
            //获取父节点对象
            Resource pResource = selectByPrimaryKey(pid);
            //全路径变量
            String fullName;


            //如果是文件
            if (resource.getDirectory().equals(Resource.DIRECTORY_FILE) && file != null) {
                String originalFilename = file.getOriginalFilename();
                String fileSuffix = "";
                String fileName = "";
                if (originalFilename.lastIndexOf(".") > 0) {
                    // 获取文件后缀
                    fileSuffix = originalFilename == null ? null :
                            originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
                    // 获取文件名称
                    fileName = originalFilename;
                } else {
                    fileName = originalFilename;
                }


                boolean flag = this.isSameName("", fileName, resource.getPid(), projectId);
                if (flag) {
                    throw new BusinessException("同一层级文件名重复，请先修改文件名");
                }

                resource.setName(fileName);
                resource.setFileSuffix(fileSuffix);
                resource.setSize(file.getSize());

                if (RESOURCE_ID.equals(resource.getPid())) {

                    fullName = baseFilePath + "/" + resource.getProjectId() + "/file/" + originalFilename;

                } else {
                    fullName = pResource.getFullName() + "/" + originalFilename;
                }

                fileOperateCommonService.upload(file.getInputStream(), fullName);

            } else {//如果是目录
                //父ID是顶级节点
                if (RESOURCE_ID.equals(resource.getPid())) {
                    fullName = baseFilePath + "/" + resource.getProjectId() + "/file/" + resource.getName();
                } else {
                    if (StringUtils.isBlank(pResource.getFullName())) {
                        throw new BusinessException("父节点全路径为空！");
                    }
                    fullName = pResource.getFullName() + "/" + resource.getName();
                }
                boolean isMkdir = fileOperateCommonService.mkdir(fullName);
                if (!isMkdir) {
                    throw new BusinessException("创建目录失败！");
                }
            }
            //全路径存入数据库中
            resource.setFullName(fullName);
            resource.setType(Resource.TYPE_RESOURCE);
            insertSelective(resource);
            //记录日志
            BdpLogUtil.log4Insert(resource);
            return resource.getId();
        } catch (Exception e) {
            throw new BusinessException(e.getMessage(), e);
        }
    }


    /**
     * 修改目录
     *
     * @param resource 修改目录
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateForDirectory(Resource resource) {
        try {
            //查询库中数据
            Resource oldResource = selectByPrimaryKey(resource.getId());
            if (oldResource == null) {
                throw new BusinessException("数据不存在");
            }

            fileOperateCommonService.getStorageAndSetThreadLocal(resource.getProjectId());

            //判断是否修改了名称
            String name = resource.getName();
            String oldName = oldResource.getName();

            if (!name.equals(oldName)) {
                String oldFullName = oldResource.getFullName();
                String newFullName = "";
                //如果是文件
                if (oldResource.getDirectory().equals(Resource.DIRECTORY_FILE)) {
                    //组装新的全路径
                    String prefix = oldFullName.substring(0, oldFullName.lastIndexOf("/") + 1);
                    newFullName = prefix + name + "." + oldResource.getFileSuffix();
                    boolean status = fileOperateCommonService.rename(oldFullName, newFullName);
                    if (!status) {
                        throw new BusinessException("修改名称失败");
                    }
                } else if (oldResource.getDirectory().equals(Resource.DIRECTORY_FOLDER)) {
                    //如果是目录
                    //组装新的全路径
                    String prefix = oldFullName.substring(0, oldFullName.lastIndexOf("/") + 1);
                    newFullName = prefix + name;
                    boolean status = fileOperateCommonService.rename(oldFullName, newFullName);
                    if (!status) {
                        throw new BusinessException("修改名称失败");
                    }
                }
                resource.setFullName(newFullName);
            } else {
                resource.setFullName(oldResource.getFullName());
            }
            updateByPrimaryKey(getUpdateDto(resource));
        } catch (Exception e) {
            throw new BusinessException(e.getMessage(), e);
        }
    }

    private Resource getUpdateDto(Resource resource) {
        Resource oldDTO = selectByPrimaryKey(resource.getId());
        if (oldDTO == null) {
            throw new BusinessException("数据不存在");
        }

        //记录日志
        BdpLogUtil.log4Update(resource, oldDTO);

        oldDTO.setFullName(resource.getFullName());
        oldDTO.setName(resource.getName());
        oldDTO.setRemark(resource.getRemark());
        return oldDTO;
    }


    /**
     * 删除目录/文件
     *
     * @param id id
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteResource(String id) {
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("删除失败！传入的参数主键为null");
        }
        try {
            //记录日志
            Resource resource = selectByPrimaryKey(id);
            if (resource == null) {
                throw new BusinessException("删除失败！对象不存在");
            }

            fileOperateCommonService.getStorageAndSetThreadLocal(resource.getProjectId());

            //删除文件或目录
            if (resource.getDirectory() == 0) {
                //判断目录下是否有资源文件，有——不可删
                if (checkData(id)) {
                    throw new BusinessException("该目录下存在资源文件，不可删除");
                }
                //判断是否存在该文件
                if (fileOperateCommonService.exists(resource.getFullName())) {
                    boolean status = fileOperateCommonService.delete(resource.getFullName(), false);
                    if (!status) {
                        throw new BusinessException("删除文件失败");
                    }
                }

            } else {
                boolean status = fileOperateCommonService.delete(resource.getFullName(), true);
                if (!status) {
                    throw new BusinessException("删除目录失败");
                }
            }

            List<String> ids = Lists.newArrayList();
            handleId(id, ids);
            this.mapper.deleteByIds(ids);
        } catch (Exception e) {
            throw new BusinessException(e.getMessage(), e);
        }
    }

    /**
     * 判断目录下是否存在资源文件
     *
     * @param id id
     * @return 是否存在资源文件
     */
    private boolean checkData(String id) {
        List<Resource> resources = mapper.selectByPid(id);
        if (resources != null && resources.size() > 0) {
            for (Resource resource : resources) {
                if (resource.getDirectory() == 0) {
                    return true;
                } else {
                    checkData(resource.getId());
                }
            }
        }
        return false;
    }

    /**
     * 处理ID集合
     *
     * @param id  id
     * @param ids ids
     */
    private void handleId(String id, List<String> ids) {
        ids.add(id);
        List<Resource> childrenList = this.mapper.selectByPid(id);
        if (childrenList != null && childrenList.size() > 0) {
            for (Resource child : childrenList) {
                handleId(child.getId(), ids);
            }
        }
    }

    /**
     * 判断同一层级目录/文件名称是否重复
     *
     * @param id   id
     * @param name name
     * @param pid  pid
     * @return 是否重复
     */
    public Boolean isSameName(String id, String name, String pid, String projectId) {
        if (StringUtils.isAnyBlank(name, pid)) {
            throw new BusinessException("请检查参数!");
        }
        boolean flag = false;
        Resource resource = new Resource();
        resource.setPid(pid);
        resource.setName(name);
        //兼容前端未改接口
        if (StringUtils.isNotBlank(projectId)) {
            resource.setProjectId(projectId);
        }
        List<Resource> list = selectList(resource);
        if (list != null && list.size() > 0) {
            if (StringUtils.isBlank(id)) {
                return true;
            }
            for (Resource dto : list) {
                if (!dto.getId().equals(id)) {
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }

    /**
     * 查询子集合
     *
     * @param directoryId 目录ID
     * @param keyWords    查询关键字
     * @param pageNo      当前页
     * @param pageSize    每页大小
     * @return 子集合
     */
    public QueryRespBean<Resource> getList(String directoryId, String projectId, String keyWords,
                                           Integer pageNo, Integer pageSize) {
        QueryRespBean<Resource> queryRespBean = new QueryRespBean<>();
        try {
            StorageResourceConf storageResourceConf = fileOperateCommonService.getStorageResourceConf(projectId);
            if (storageResourceConf == null) {
                logger.error("存储资源未设置，请先设置存储资源！");
                throw new BusinessException("存储资源未设置，请先设置存储资源！");
            }
            com.github.pagehelper.PageHelper.startPage(pageNo, pageSize);
            Page<Resource> dataList = this.mapper.getList(directoryId, storageResourceConf.getId(), projectId, keyWords);
            List<Resource> list = dataList.getResult();
            if (CollectionUtils.isNotEmpty(list)) {
                for (Resource resource : list) {
                    String sizeStr = "";
                    if (resource.getSize() != null && resource.getDirectory() == 0) {
                        long size = resource.getSize();
                        String unit = FileUtils.formatNumber(size);
                        Double sized = FileUtils.formatAmountUnit(unit, size);
                        sizeStr = sized.toString() + unit;
                    }
                    resource.setSizeStr(sizeStr);
                }
            }
            queryRespBean.setResult(dataList);
            BdpLogUtil.log4Query(queryRespBean);
            return queryRespBean;
        } catch (Exception e) {
            throw new BusinessException(e.getMessage(), e);
        }
    }

    public void downloadFile(String resourceId, HttpServletResponse response) {
        Resource resource = selectByPrimaryKey(resourceId);
        if (resource == null) {
            throw new BusinessException("文件不存在");
        }
        String filePath = resource.getFullName();

        logger.info("下载的文件路径为：{}", filePath);
        fileOperateCommonService.getStorageAndSetThreadLocal(resource.getProjectId());

        try {
            InputStream inputStream = fileOperateCommonService.open(filePath);
            // 设置文件ContentType类型，这样设置，会自动判断下载文件类型
            response.setContentType("multipart/form-data");
            // 设置文件头：最后一个参数是设置下载文件名
            String fileName = FileUtils.getNameByPath(filePath);
            logger.info("下载的文件名称为：{}", fileName);
            fileName = URLEncoder.encode(fileName, "utf-8");
            // 处理空格转为加号的问题
            String dealedFileName = fileName.replaceAll("\\+", "%20");
            logger.info("转码后的文件名为：{}", dealedFileName);
            response.setHeader("Content-Disposition", "attachment;filename=" + dealedFileName);
            IOUtils.copy(inputStream, response.getOutputStream());
            IOUtils.closeQuietly(inputStream);

            //记录日志
            String logTitle = "下载文件：【" + resource.getName() + "】";
            BdpLogUtil.log("文件管理模块",logTitle, PlatformConstant.OpType.update);

        } catch (IOException ioe) {
            throw new BusinessException("下载文件失败!");
        }
    }

    /**
     * @param lastUpdateTime 上次更新时间
     * @param list           路径列表
     * @return 变更数量
     */
    public int countLatestModify(Date lastUpdateTime, List<String> list) {
        return this.mapper.countLatestModify(lastUpdateTime, list);
    }

    /**
     * 通过资源ID列表查询文件全路径列表
     *
     * @param resourceIdList 资源ID列表
     * @return 路径列表
     */
    public List<String> selectFullNameByIdList(List<String> resourceIdList) {
        return this.mapper.selectFullNameByIdList(resourceIdList);
    }

    /**
     * 查询判读文件列表
     */
    @Transactional(readOnly = true)
    public QueryRespBean<Resource> getFileResList(String projectId,
                                                  String directoryId,
                                                  String name,
                                                  Integer status,
                                                  Integer pageNo,
                                                  Integer pageSize) throws Exception {
        QueryRespBean<Resource> queryRespBean = new QueryRespBean<>();
        com.github.pagehelper.PageHelper.startPage(pageNo, pageSize);

        Page<Resource> resourceList = resourceMapper.getFileResList(projectId, directoryId, name, status);

        if (CollectionUtils.isNotEmpty(resourceList)) {
            List<String> userIdList = new ArrayList<>();
            for (Resource resource : resourceList) {
                resource.setStatusString(ResourceStatus.getDescByCode(resource.getStatus()));

                if (StringUtils.isNotEmpty(resource.getCreatedBy())) {
                    userIdList.add(resource.getCreatedBy());
                }
            }
        }
        valueConvert(resourceList);
        queryRespBean.setResult(resourceList);
        BdpLogUtil.log4Query(queryRespBean);
        return queryRespBean;
    }

    private void valueConvert(Page<Resource> resourceList) {
        //循环组装请求数据
        Map<String, Set<String>> convertFormData = new HashMap<>();
        for (Resource resource : resourceList) {
            BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, resource.getCreatedBy());
        }
        if (convertFormData.size() > 0) {
            //获取请求结果
            Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
            //循环设置Alias或Name的值
            for (Resource resource : resourceList) {
                resource.setCreatedBy(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER,
                        resource.getCreatedBy()));
            }
        }
    }

    /**
     * 删除资源
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteFileRes(String ids) {
        CheckParaUtils.checkStringValidity(ids, logger, "没有传入待删除的id");

        String[] idArr = ids.split(Constants.COMMA);
        try {
            for (String id : idArr) {
                // 先删除文件,再删除数据表中数据
                Resource resource = this.selectByPrimaryKey(id);
                CheckParaUtils.checkDbObjectValidity(resource, logger, avicit.platform6.commons.utils.StringUtils.format("没有查到数据，请确保id:{}的资源是否存在", id));

                fileOperateCommonService.getStorageAndSetThreadLocal(resource.getProjectId());

                // 删除HDFS文件
                if (resource.getDirectory() == 0) {
                    // 判断hdfs是否存在该文件
                    if (fileOperateCommonService.exists(resource.getFullName())) {
                        boolean status = fileOperateCommonService.delete(resource.getFullName(), false);
                        if (!status) {
                            throw new BusinessException("hdfs删除文件失败");
                        }
                    }
                }

                // 记录日志
                BdpLogUtil.log4Delete(resource);

                this.deleteByPrimaryKey(resource);
            }
        } catch (Exception e) {
            logger.error("删除文件异常{}", e.getMessage());
            throw new BusinessException("删除文件失败," + e.getMessage());
        }
        return true;
    }

    /**
     * 重命名
     *
     * @param resource
     */
    @Transactional(rollbackFor = Exception.class)
    public void renameFileRes(Resource resource) {
        logger.info("重命名资源,参数为{}", JSONObject.toJSONString(resource));
        CheckParaUtils.checkStringValidity(resource.getName(), logger, "名称必填");

        Resource oldResource = this.selectByPrimaryKey(resource.getId());
        CheckParaUtils.checkDbObjectValidity(oldResource, logger,
                avicit.platform6.commons.utils.StringUtils.format("没有查到数据，请确保id:{}的资源是否存在", resource.getId()));

        oldResource.setName(resource.getName());
        this.updateByPrimaryKeySelective(oldResource);
    }

    /**
     * 重新计算
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void recompute(String id) {
        Resource resource = this.selectByPrimaryKey(id);
        CheckParaUtils.checkDbObjectValidity(resource, logger,
                avicit.platform6.commons.utils.StringUtils.format("没有查到数据，请确保id:{}的资源是否存在", id));

        // 调用dds接口
        execute(resource, ExecuteType.REPEAT_RUNNING);
    }

    /**
     * 停止计算
     *
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void stopCompute(String id) {
        Resource resource = this.selectByPrimaryKey(id);
        CheckParaUtils.checkDbObjectValidity(resource, logger,
                avicit.platform6.commons.utils.StringUtils.format("没有查到数据，请确保id:{}的资源是否存在", id));

        // 调用dds接口
        execute(resource, ExecuteType.STOP);
    }

    private void execute(Resource resource, ExecuteType executeType) {
        ResOtherInfoDto otherInfoDto = JSONObject.parseObject(resource.getOtherInfo(), ResOtherInfoDto.class);
        CheckParaUtils.checkObjectValidity(otherInfoDto, logger, "请检查参数");

        String processDefinitionId = otherInfoDto.getProcessDefinitionId();
        String processInstanceId = otherInfoDto.getProcessInstanceId();

        logger.info("execute command, process instance id:{}, execute type:{}", processInstanceId, executeType);

        if (StringUtils.isEmpty(processDefinitionId) && StringUtils.isEmpty(processInstanceId)) {
            throw new BusinessException("请检查参数");
        }

        execService.execute(processDefinitionId, processInstanceId, executeType);
    }

    @Transactional(rollbackFor = Exception.class)
    public void uploadFileRes(ResUploadDto resUploadDto) {
        Long startTime = System.currentTimeMillis();
        logger.info("进入开始上传接口:{}, 参数：{}", startTime, resUploadDto.toString());
        fileCommonService.checkBeforeUpload(resUploadDto);

        // 数据表中写入数据
        MultipartFile file = resUploadDto.getFile();
        String originalFilename = file.getOriginalFilename();
        String fileFullPath = resUploadDto.getHdfsPath() + Constants.SINGLE_SLASH + originalFilename;
        String fileSuffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);

        Resource resource = null;
        synchronized (this) {
            Resource resourceQuery = new Resource();
            resourceQuery.setFullName(fileFullPath);
            resource = this.selectOne(resourceQuery);

            if (resource == null) {
                resource = new Resource();
                resource.setId(ComUtil.getId());
                resource.setName(originalFilename);
                resource.setProjectId(resUploadDto.getProjectId());
                resource.setType(0);
                resource.setSize(resUploadDto.getFileSize());
                resource.setFileSuffix(fileSuffix);
                resource.setPid(resUploadDto.getDirectoryId());
                resource.setFullName(fileFullPath);
                resource.setDirectory(0);
                resource.setStatus(ResourceStatus.UPLOADING.getCode());
                this.insert(resource);

                // 记录日志
                try {
                    BdpLogUtil.log4Insert(resource);
                } catch (Exception e) {
                    logger.error("调用平台服务记录日志异常:{}", e.getMessage());
                }
            }
        }

        try {
            fileOperateCommonService.getStorageAndSetThreadLocal(resUploadDto.getProjectId());
            fileCommonService.uploadFile(resUploadDto);

            Long endTime = System.currentTimeMillis();
            logger.info("结束上传时间为：{}，耗时：{}", endTime, endTime - startTime);

            resource.setStatus(ResourceStatus.UPLOAD_SUCCESS.getCode());
            this.updateByPrimaryKeySelective(resource);
        } catch (Exception e) {
            resource.setStatus(ResourceStatus.UPLOAD_FAIL.getCode());
            this.updateByPrimaryKeySelective(resource);
            logger.error(e.getMessage(), e);
            throw new BusinessException(e.getMessage());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void reUpload(ResUploadDto resUploadDto) {
        Long startTime = System.currentTimeMillis();
        logger.info("进入开始上传接口:{}, 参数：{}", startTime, resUploadDto.toString());
        fileCommonService.checkBeforeUpload(resUploadDto);

        // 更新数据表中数据
        MultipartFile file = resUploadDto.getFile();
        String originalFilename = file.getOriginalFilename();
        String fileFullPath = resUploadDto.getHdfsPath() + Constants.SINGLE_SLASH + originalFilename;
        String fileSuffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        Resource resource = this.selectByPrimaryKey(resUploadDto.getId());
        resource.setName(originalFilename);
        resource.setType(0);
        resource.setSize(file.getSize());
        resource.setFileSuffix(fileSuffix);
        resource.setFullName(fileFullPath);
        resource.setDirectory(0);
        resource.setStatus(ResourceStatus.UPLOADING.getCode());
        this.updateByPrimaryKeySelective(resource);

        try {
            fileOperateCommonService.getStorageAndSetThreadLocal(resUploadDto.getProjectId());
            fileCommonService.uploadFile(resUploadDto);

            Long endTime = System.currentTimeMillis();
            logger.info("结束上传时间为：{}，耗时：{}", endTime, endTime - startTime);

            resource.setStatus(ResourceStatus.UPLOAD_SUCCESS.getCode());
            this.updateByPrimaryKeySelective(resource);
        } catch (Exception e) {
            resource.setStatus(ResourceStatus.UPLOAD_FAIL.getCode());
            this.updateByPrimaryKeySelective(resource);
            logger.error(e.getMessage(), e);
            throw new BusinessException(e.getMessage());
        }
    }

    public List<Resource> getFileListByLatestModify(Date lastUpdateTime, List<String> directoryList) {
        return this.mapper.getFileListByLatestModify(lastUpdateTime, directoryList);
    }
}
